package com.thirtydays.frame.util.ext

import androidx.annotation.MainThread
import androidx.annotation.Nullable
import androidx.lifecycle.*
import java.util.concurrent.atomic.AtomicBoolean


/**
 * @创建者：小垚
 * @时间：2022/7/1  9:48
 * @描述：解决LiveData 数据倒灌的问题
 */
class SingleLiveData<T> : MutableLiveData<T>() {
    private val mPendingMap = mutableMapOf<Observer<in T?>, AtomicBoolean>()

    @MainThread
    override fun observe(owner: LifecycleOwner, observer: Observer<in T?>) {
        val lifecycle: Lifecycle = owner.lifecycle
        if (lifecycle.currentState === Lifecycle.State.DESTROYED) {
            return
        }
        mPendingMap[observer] = AtomicBoolean(false)
        lifecycle.addObserver(LifecycleEventObserver { source: LifecycleOwner?, event: Lifecycle.Event ->
            if (event == Lifecycle.Event.ON_DESTROY) {
                mPendingMap.remove(observer)
            }
        })
        super.observe(owner) { t: T ->
            val pending = mPendingMap[observer]
            if (pending != null && pending.compareAndSet(true, false)) {
                observer.onChanged(t)
            }
        }
    }

    @MainThread
    override fun observeForever(observer: Observer<in T?>) {
        mPendingMap[observer] = AtomicBoolean(false)
        super.observeForever(observer)
    }

    @MainThread
    override fun removeObserver(observer: Observer<in T?>) {
        mPendingMap.remove(observer)
        super.removeObserver(observer)
    }

    @MainThread
    override fun removeObservers(owner: LifecycleOwner) {
        mPendingMap.clear()
        super.removeObservers(owner)
    }

    @MainThread
    override fun setValue(@Nullable t: T) {
        for (value in mPendingMap.values) {
            value.set(true)
        }
        super.setValue(t)
    }
}